package com.example.fengyungo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.example.fengyungo.constant.PayConstant;
import com.example.fengyungo.domain.dto.DriverOrderDTO;
import com.example.fengyungo.domain.entity.Order;
import com.example.fengyungo.domain.pojo.OrderResult;
import com.example.fengyungo.service.DriverService;
import com.example.fengyungo.service.DriverVerifyService;
import com.example.fengyungo.service.OrderResultService;
import com.example.fengyungo.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class PayServiceImpl implements PayService {

    // 获取配置文件中的配置信息
    // 应用ID,您的APPID，收款账号既是您的APPID对应支付宝账号
    @Value("${alipay.app-id}")
    private String appId;

    // 商户私钥 您的PKCS8格式RSA2私钥
    @Value("${alipay.private-key}")
    private String privateKey;

    // 支付宝公钥
    @Value("${alipay.public-key}")
    private String publicKey;

    // 服务器异步通知页面路径
    @Value("${alipay.notify-url}")
    private String notifyUrl;

    // 签名方式
    @Value("${alipay.sign-type}")
    private String signType;

    // 字符编码格式
    @Value("${alipay.charset}")
    private String charset;

    // 支付宝网关
    @Value("${alipay.gateway-url}")
    private String gatewayUrl;

    private final String format = "json";

    @Autowired
    private OrderResultService orderResultService;

    @Autowired
    private DriverVerifyService driverVerifyService;

    @Autowired
    private DriverService driverService;

    /**
     * 获取订单信息用于用户向平台支付
     *
     * @param order Order
     * @return AlipayTradeAppPayResponse
     */
    @Override
    public AlipayTradeAppPayResponse getOrderStr(Order order) throws AlipayApiException {
        AlipayClient alipayClient =
                new DefaultAlipayClient(gatewayUrl, appId, privateKey, format, charset, publicKey, signType);
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        request.setNotifyUrl(notifyUrl);

        log.info("order=" + order);

        JSONObject bizContent = new JSONObject();
        // out_trade_no必选string(64)，商户网站唯一订单号。由商家自定义，64个字符以内，仅支持字母、数字、下划线且需保证在商户端不重复。
        // 【示例值】70501111111S001111119
        bizContent.put("out_trade_no", order.getNumber());
        // total_amount必选string(9)，订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]，金额不能为0
        // 【示例值】9.00
        bizContent.put("total_amount", order.getPrice());
        // subject必选string(256)，订单标题。注意：不可使用特殊字符，如 /，=，& 等。
        // 【示例值】大乐透
        bizContent.put("subject", order.getBegin() + "→" + order.getEnd());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");
        // time_expire可选string(32)，绝对超时时间，格式为yyyy-MM-dd HH:mm:ss
        // 【示例值】2016-12-31 10:05:00
        // bizContent.put("time_expire", "2022-08-01 22:00:00");

        //// 商品明细信息，按需传入
        // JSONArray goodsDetail = new JSONArray();
        // JSONObject goods1 = new JSONObject();
        // goods1.put("goods_id", "goodsNo1");
        // goods1.put("goods_name", "子商品1");
        // goods1.put("quantity", 1);
        // goods1.put("price", 0.01);
        // goodsDetail.add(goods1);
        // bizContent.put("goods_detail", goodsDetail);
        bizContent.put("goods_detail", order);

        //// 扩展信息，按需传入
        // JSONObject extendParams = new JSONObject();
        // extendParams.put("sys_service_provider_id", "2088511833207846");
        // bizContent.put("extend_params", extendParams);

        request.setBizContent(bizContent.toString());
        return alipayClient.sdkExecute(request);
    }

    /**
     * 平台退款给用户
     *
     * @param order Order
     * @return AlipayTradeRefundResponse
     */
    @Override
    public AlipayTradeRefundResponse refund(Order order) throws AlipayApiException {
        AlipayClient alipayClient =
                new DefaultAlipayClient(gatewayUrl, appId, privateKey, format, charset, publicKey, signType);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();

        // 获取OrderResult
        OrderResult orderResult = orderResultService.getOrderResultByOutTradeNo(order.getNumber());

        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", orderResult.getTradeNo());
        bizContent.put("refund_amount", orderResult.getTotalAmount());
        // bizContent.put("out_request_no", order.getNumber());

        //// 返回参数选项，按需传入
        // JSONArray queryOptions = new JSONArray();
        // queryOptions.add("refund_detail_item_list");
        // bizContent.put("query_options", queryOptions);

        request.setBizContent(bizContent.toString());
        return alipayClient.execute(request);
    }

    /**
     * 平台向司机转账
     *
     * @param driverOrderDTO DriverOrderDTO
     * @return AlipayFundTransUniTransferResponse
     */
    @Override
    public AlipayFundTransUniTransferResponse payToDriver(DriverOrderDTO driverOrderDTO) throws AlipayApiException {
        AlipayClient alipayClient =
                new DefaultAlipayClient(gatewayUrl, appId, privateKey, format, charset, publicKey, signType);
        // 构造请求参数以调用接口
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();

        log.info("privateKey="+privateKey);

        // 设置转账业务的标题
        model.setOrderTitle(PayConstant.FENG_YUN_GO_TRANSFER);

        // 设置描述特定的业务场景，单笔无密转账固定为 DIRECT_TRANSFER。
        model.setBizScene("DIRECT_TRANSFER");

        // 设置转账业务请求的扩展参数
        // model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");

        // 设置业务备注
        model.setRemark(PayConstant.FENG_YUN_GO_ORDER_RESULT);

        // 商家侧唯一订单号，由商家自定义。对于不同转账请求，商家需保证该订单号在自身系统唯一。
        model.setOutBizNo(driverOrderDTO.getNumber());

        // 设置订单总金额
        model.setTransAmount(String.valueOf(driverOrderDTO.getPrice()));

        // 设置业务产品码。销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD。
        model.setProductCode("TRANS_ACCOUNT_NO_PWD");

        // 设置收款方信息
        // Participant payeeInfo = new Participant();
        // payeeInfo.setIdentity("2088722029328351");
        // payeeInfo.setIdentityType("ALIPAY_USER_ID");
        // model.setPayeeInfo(payeeInfo);

        // 获取司机姓名、手机号
        String name = driverVerifyService.getDriverNameById(driverOrderDTO.getId());
        String phone = driverService.getPhoneById(driverOrderDTO.getId());

        Participant payeeInfo = new Participant();
        // 当 identity_type=ALIPAY_LOGON_ID 时，填写支付宝登录号。示例值：186xxxxxxxx。
        payeeInfo.setIdentity(phone);
        // 参与方真实姓名。如果非空，将校验收款支付宝账号姓名一致性。
        // 当 identity_type=ALIPAY_LOGON_ID 时，本字段必填。若传入该属性，则在支付宝回单中将会显示这个属性。
        payeeInfo.setName(name);
        payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
        model.setPayeeInfo(payeeInfo);

        // 设置原支付宝业务单号
        // model.setOriginalOrderId("20190620110075000006640000063056");

        request.setBizModel(model);
        // 公钥证书的 certificateExecute（）修改为 RSA2 密钥的 execute（）
        return alipayClient.execute(request);
    }
}
